<template>
  <div class="Input-container">
    <form @submit.prevent="submit">
      <!-- 输入框 -->
      <div class="from-item" v-for="(item, index) in inputArrRef" :key="index">
        <input
          ref="Move"
          :type="item.type"
          v-model.trim="item[item.corresponding]"
          @blur="validate(item, index)"
          @input="synchronizationData"
        />

        <span class="err" ref="err" v-if="item.err"></span>
        <span class="bar"></span>
        <label for="username">{{ item.title }}</label>
      </div>
      <!-- 功能区域 -->
      <div class="FunZone">
        <slot name="automatic"></slot>
        <slot name="forget"></slot>
      </div>
      <!-- 按钮 -->
      <button
        type="submit"
        :disabled="loading"
        :class="{ disabled: loading, but: true }"
      >
        {{ !loading ? btn : "加载中" }}
      </button>
    </form>
  </div>
</template>
  
<script setup>
import { storeToRefs } from "pinia";
import { useUserStore } from "@/store/useUserStore.js";
import { vaildates } from "@/util/validate.js";
import { ref, watchEffect, onMounted, computed } from "vue";
import { deepClone } from "@/util/copy.js";

const props = defineProps({
  inputArr: {
    type: Array,
    default: () => [],
  },
  btn: {
    type: String,
    required: true,
  },
  Errer: {
    type: String,
    required: true,
  },
});

const inputArrRef = computed(() => deepClone(props.inputArr));


const store = useUserStore();
// 从仓库中解构数据
const { loading } = storeToRefs(store);
const err = ref([]); // 错误提示
const Move = ref([]); // 输入
const emit = defineEmits(["submit", "input"]);

// 监听数据的数据变化
onMounted(() => {
  watchEffect(() => {
    inputArrRef.value.forEach((item, index) => {
      if (item[item.corresponding] === "" && Move.value.length !== 0) {
        Move.value[index].className = "";
      } else {
        Move.value[index].className = "Move";
      }
    });
  });
});
// 错误是否出现
function validate(item, index) {
  let i = index;
  // 用于判断传入数据是否有err属性
  if (!item.hasOwnProperty("err")) {
    return;
  }
  // errDom是否为0
  if (Object.keys(err.value).length === 0) {
    return;
  }
  // 如果errDom数组小于了index代表有些属性中没有规则验证
  if (Object.keys(err.value).length <= index) {
    i = Object.keys(err.value).length - 1;
  }
  const msg = vaildates(item);
  if (msg) {
    err.value[i].style.display = "block";
    err.value[i].innerHTML = msg;
  } else {
    err.value[i].style.display = "none";
  }
  if (!item[item.corresponding]) {
    Move.value[index].className = "";
  } else {
    Move.value[index].className = "Move";
  }
}
// 同步数据
function synchronizationData() {
  let state = true;
  inputArrRef.value.forEach((item) => {
    if (vaildates(item)) {
      state = false;
    }
  });
  if(state){
    emit("input", inputArrRef.value);
  }
}

// 提交数据
function submit() {
  const info = {};
  let state = true;
  inputArrRef.value.forEach((item) => {
    if (vaildates(item)) {
      state = false;
    } else {
      info[item.corresponding] = item[item.corresponding];
    }
  });
  if (!state) {
    ElMessage.error(props.Errer);
    return;
  }
  emit("submit", info);
}
</script>
  
  <style lang="less" scoped>
@import "@/styles/var.less";
.Input-container {
  height: 100%;
  width: 100%;

  .from-item {
    position: relative;
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid @primary;
    margin: 40px 0;
    color: @primary;
    input {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 9;
      background-color: transparent;
      width: 100%;
      border: none;
      height: 100%;
      outline: none;
      padding: 0 10px;
      &.Move ~ .bar,
      &:focus ~ .bar {
        width: 100%;
      }
      &.Move ~ label,
      &:focus ~ label {
        color: #5264ae;
        transform: translateY(-25px);
        font-size: 16px;
      }
    }
    label {
      position: absolute;
      left: 0;
      top: 0;
      transition: all 0.2s linear;
      margin-left: 10px;
      font-weight: bold;
    }
    .bar {
      transition: all 0.2s linear;
      border-bottom: 3px solid #5264ae;
      width: 0;
      position: absolute;
      left: 50%;
      bottom: 0;
      transform: translate(-50%, 0);
    }
    .err {
      position: absolute;
      left: 0;
      top: 30px;
      font-size: 12px;
      color: @danger;
      display: none;
    }
  }
  .FunZone {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
  }
  .but {
    width: 100%;
    height: 40px;
    letter-spacing: 30px;
    border: 0;
    background-color: @primary;
    color: @white;
    border-radius: 5px;
    cursor: pointer;
  }
  .disabled {
    background-color: @disabled !important;
    cursor: not-allowed;
  }
}
</style>